protect nginx temp directories from purge walks - #66
Open
hsntgm wants to merge 1 commit into
Open
Conversation
When a purge_all, wildcard, or vary‑aware exact purge performs a full directory walk of the cache root, it may descend into nginx's temporary directories (fastcgi_temp, proxy_temp, etc.) if they are nested under the cache path. This is a common misconfiguration, often copied from tutorials, where users set *temp_path to a subdirectory of *cache_path to ensure the final rename() is atomic and fast. Deleting in‑flight temporary files corrupts responses and causes sporadic, hard‑to‑debug errors under load, especially during high‑traffic periods. Add a hard‑coded list of the default basenames of nginx's temp directories (client_temp, client_body_temp, fastcgi_temp, proxy_temp, scgi_temp, uwsgi_temp). The purge walk now skips any directory whose path component exactly matches one of these names via the pre_tree_handler (returning NGX_DECLINED). Every file‑level delete handler also checks the path to avoid deletion if the directory skip fails. The list is intentionally static and name‑based rather than read from the live *temp_path directives: the purge walk runs long after configuration parsing, inside a worker handling the purge request or servicing the background queue, with no cheap way to retrieve every protocol's temp_path. These names are nginx's compiled‑in defaults and cover the overwhelming majority of real‑world installations. This guard is a pure safety net: it only causes files to be skipped, never causes a file that would otherwise be left alone to be deleted.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This patch adds a safety mechanism to prevent purge walks (purge_all,
wildcard, and vary‑aware exact purges) from deleting files inside
Nginx's own temporary directories.
The problem:
on the same filesystem for atomic rename().
*_cache_path, e.g.:
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=z:10m;
proxy_temp_path /var/cache/nginx/proxy_temp;
into proxy_temp and deletes in‑flight temporary files, corrupting
responses and causing hard‑to‑debug errors under load.
The solution:
client_temp, client_body_temp, fastcgi_temp, proxy_temp, scgi_temp,
uwsgi_temp.
whose path component exactly matches one of these names, causing
ngx_walk_tree() to skip that entire subtree.
exact) as a fallback, ensuring protection even on older nginx
versions that don't support directory skipping.
The list is intentionally static and name‑based rather than read from
live *_temp_path directives, because the purge walk runs long after
configuration parsing, with no cheap way to retrieve every protocol's
temp_path at that time. These names are Nginx's compiled‑in defaults
and cover the overwhelming majority of real‑world installations.
This guard is a pure safety net: it only ever causes files to be
SKIPPED, never causes a file that would otherwise be left alone to be
deleted.